Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IonExchange0D Unit Model and Costing Improvements #1139

Merged
merged 39 commits into from
Dec 15, 2023

Conversation

kurbansitterley
Copy link
Contributor

@kurbansitterley kurbansitterley commented Sep 19, 2023

Fixes/Resolves:

  • Improved/updated costing relationships from most recent release of EPA-WBS model.
  • Add single_use option for regeneration and associated costing
  • Remove bed_capacity_param variable and associated constraints to improve model stability/solvability.

Summary/Motivation:

Changes to model made as results of continuing PFAS analysis.

  • bed_capacity_param was found to explode to massive values (>1e+20) under many model conditions, resulting in unbounded/infeasible solves (or optimal solves that were non-sensical). This PR removes that variable and all associated constraints and expressions from the model. The only place this variable was found to be necessary was in the calculation of estimated breakthrough times for the trapezoid approach used for steady-state effluent concentration tb_traps. A suitable replacement was used (essentially the eq_clark_1 constraint)
  • The regressions used for calculating vessel/tank costs were updated by the EPA and are applied here. They provide better economy of scale.

Changes proposed in this PR:

  • remove bed_capacity_param, kinetic_param and associated constraints/expressions
  • update costing regressions for tank/vessels based on recent EPA-WBS model
  • add single_use CONFIG option that assumes entire bed is replaced rather than regenerated
    • when this is used, there is no regenerant is costed
  • modify docs to reflect all these changes

Legal Acknowledgement

By contributing to this software project, I agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the license terms described in the LICENSE.txt file at the top level of this directory.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

@kurbansitterley kurbansitterley added the model dev team Issues directly related to the model development team label Sep 19, 2023
@kurbansitterley kurbansitterley self-assigned this Sep 19, 2023
@codecov
Copy link

codecov bot commented Sep 19, 2023

Codecov Report

Attention: 1 lines in your changes are missing coverage. Please review.

Comparison is base (2ddc831) 94.27% compared to head (0f7558d) 94.27%.

Files Patch % Lines
watertap/costing/unit_models/ion_exchange.py 96.96% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1139   +/-   ##
=======================================
  Coverage   94.27%   94.27%           
=======================================
  Files         357      357           
  Lines       36011    35981   -30     
=======================================
- Hits        33950    33922   -28     
+ Misses       2061     2059    -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ksbeattie ksbeattie added the Priority:Normal Normal Priority Issue or PR label Sep 21, 2023
@kurbansitterley kurbansitterley marked this pull request as ready for review September 21, 2023 20:25
hunterbarber

This comment was marked as duplicate.

Copy link
Contributor

@hunterbarber hunterbarber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No quarrels with the costing changes. I do have a question regarding the single_use condition which a lot of the changes are surrounding the conditional with this port. Is the regen port containing solutes, resin, or both? See other comments regarding mass balance perspective.

@@ -80,7 +83,7 @@ The model provides three ports (Pyomo notation in parenthesis):

* Inlet port (inlet)
* Outlet port (outlet)
* Regeneration port (regen)
* Regeneration port (regen, only if not using ``single_use`` resin configuration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its slightly confusing from a mass balance perspective. If set to single_use, inlet == outlet so how is mass removed from a modeling perspective? There is no spent resin stream that would then be regenerated with x efficiency and then added as the regen stream, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm maybe a poor choice of words on my part. The mass balance is handled the same as before where effluent concentration is estimated via trapezoid rule, which is then used to set process_flow.mass_transfer_term (see e.g., eq_mass_transfer_target_fr - I think this is pretty much identical to how GAC does it) . Without single-use, that flows to the regeneration_stream but with single-use it goes nowhere. There was never any regeneration efficiency in the model, so anything that flowed to that port was assumed to be removed via regeneration (which is not handled by the model; a user could attach a separate unit process as a regen handling process if they wanted.

But maybe there is virtue in having the removed mass flow somewhere rather than a black hole.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember this 'into the void' method when originally developing the model.

I think I'm still confused that if the contaminants are going 'into the void' and the resin is also not modeled with a pseudo-species method, what is the intention of the regeneration_stream? i.e., if someone wanted to customize a regen or waste handling unit, what is this stream/port accomplishing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regeneration_stream could be used to connect a brine/regen management unit to it, as you say... but it is a good point; I imagine the bigger challenge in managing IX regen streams is the high salinity/concentration of regenerant they typically contain rather than the flow of removed species, so one could argue the regeneration stream shoudl contain the regenerant rather than the target_ion (if it is to contain anything). But that would require some more development to accomplish and likely carries its own headaches...

I'll have to think about this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up- I added the regeneration_stream into the model for all CONFIGs (i.e. undoing what I had initially implemented). I also added back backwashing/rinsing costs/params/expressions for the single_use option. Now only regenerant costs are excluded with the single_use configuration.

Copy link
Contributor

@adam-a-a adam-a-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a couple of comments here and there

@adam-a-a
Copy link
Contributor

@kurbansitterley I know you probably realized already, but there is a merge conflict likely due to the reformulation/movement of costing files in #1122

@kurbansitterley kurbansitterley marked this pull request as draft September 28, 2023 20:16
@hunterbarber
Copy link
Contributor

hunterbarber commented Nov 29, 2023

@kurbansitterley Is this waiting on anything other than review? I will review again if these failing checks are workflow incidental.

@kurbansitterley
Copy link
Contributor Author

@kurbansitterley Is this waiting on anything other than review? I will review again if these failing checks are workflow incidental.

Yes I wanted to wait for #1175 to be merged since it also changes the IX costing.

@ksbeattie ksbeattie added Priority:High High Priority Issue or PR and removed Priority:Normal Normal Priority Issue or PR labels Dec 7, 2023
@bknueven
Copy link
Contributor

bknueven commented Dec 8, 2023

@kurbansitterley let me know if you want assistance resolving the conflicts post-#1175.

Copy link
Contributor

@hunterbarber hunterbarber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing changes since last review, it seemed good to go. The single comment could be addressed but tedious and technically not incorrect.

assert value(m.fs.ion_exchange.partition_ratio) == pytest.approx(
235.99899, rel=1e-3
)
results_dict = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty unsightly and could get cleaned up. That is why we use approx after all, I think I include 4 significant figures and pytest to 1e-3. This applies to a lot of code across the test files.

Copy link
Contributor Author

@kurbansitterley kurbansitterley Dec 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't disagree, was trying to move fast. Ask and ye shall receive.

@lbianchi-lbl lbianchi-lbl enabled auto-merge (squash) December 14, 2023 23:25
@lbianchi-lbl lbianchi-lbl merged commit f45c977 into watertap-org:main Dec 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
model dev team Issues directly related to the model development team Priority:High High Priority Issue or PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants